home *** CD-ROM | disk | FTP | other *** search
/ Amiga Games Extra 1996 September / Amiga Games Extra CD-ROM 9-1996.iso / userbox / publicdomain / vim-4.2 / src / pty.c < prev    next >
C/C++ Source or Header  |  1996-06-09  |  13KB  |  561 lines

  1. /* vi:set ts=4 sw=4:
  2.  *
  3.  * VIM - Vi IMproved            by Bram Moolenaar
  4.  *
  5.  * Do ":help uganda"  in Vim to read copying and usage conditions.
  6.  * Do ":help credits" in Vim to see a list of people who contributed.
  7.  */
  8.  
  9. /*
  10.  * The stuff in this file mostly comes from "screen".
  11.  * Copied from "pty.c" and "putenv.c".
  12.  *
  13.  * It has been modified a little bit to work better with Vim.
  14.  */
  15.  
  16. /* Copyright (c) 1993
  17.  *        Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  18.  *        Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  19.  * Copyright (c) 1987 Oliver Laumann
  20.  *
  21.  * This program is free software; you can redistribute it and/or modify
  22.  * it under the terms of the GNU General Public License as published by
  23.  * the Free Software Foundation; either version 2, or (at your option)
  24.  * any later version.
  25.  *
  26.  * This program is distributed in the hope that it will be useful,
  27.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  28.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  29.  * GNU General Public License for more details.
  30.  *
  31.  * You should have received a copy of the GNU General Public License
  32.  * along with this program (see the file COPYING); if not, write to the
  33.  * Free Software Foundation, Inc.,
  34.  * 59 Temple Place - Suite 330, Boston, MA    02111-1307, USA
  35.  *
  36.  ****************************************************************
  37.  */
  38.  
  39. /* #include "rcs.h" */
  40. /* RCS_ID("$Id: pty.c,v 1.6 1994/05/31 12:32:44 mlschroe Exp $ FAU") */
  41.  
  42. #include "vim.h"
  43. #include "proto.h"
  44.  
  45. #define debug(x)
  46. #define debug1(x, y)
  47.  
  48. /* #include <sys/types.h> */
  49. /* #include <sys/stat.h> */
  50. #ifdef HAVE_FCNTL_H
  51. # include <fcntl.h>
  52. #endif
  53. #include <signal.h>
  54.  
  55. /* #include "config.h" */
  56. /* #include "screen.h" */
  57.  
  58. #ifndef sun
  59. #include <sys/ioctl.h>
  60. #endif
  61.  
  62. #if defined(sun) && defined(LOCKPTY) && !defined(TIOCEXCL)
  63. #include <sys/ttold.h>
  64. #endif
  65.  
  66. #ifdef ISC
  67. # include <sys/tty.h>
  68. # include <sys/sioctl.h>
  69. # include <sys/pty.h>
  70. #endif
  71.  
  72. #ifdef sgi
  73. # include <sys/sysmacros.h>
  74. #endif /* sgi */
  75.  
  76. /* #include "extern.h" */
  77.  
  78. #if defined(_INCLUDE_HPUX_SOURCE) && !defined(hpux)
  79. # define hpux
  80. #endif
  81.  
  82. /*
  83.  * if no PTYRANGE[01] is in the config file, we pick a default
  84.  */
  85. #ifndef PTYRANGE0
  86. # define PTYRANGE0 "qpr"
  87. #endif
  88. #ifndef PTYRANGE1
  89. # define PTYRANGE1 "0123456789abcdef"
  90. #endif
  91.  
  92. /* extern int eff_uid; */
  93.  
  94. #if !(defined(sequent) || defined(_SEQUENT_) || defined(SVR4))
  95. # ifdef hpux
  96. static char PtyProto[] = "/dev/ptym/ptyXY";
  97. static char TtyProto[] = "/dev/pty/ttyXY";
  98. # else
  99. static char PtyProto[] = "/dev/ptyXY";
  100. static char TtyProto[] = "/dev/ttyXY";
  101. # endif /* hpux */
  102. #endif
  103.  
  104. static void initpty __ARGS((int));
  105.  
  106. /*
  107.  *    Open all ptys with O_NOCTTY, just to be on the safe side
  108.  *    (RISCos mips breaks otherwise)
  109.  */
  110. #ifndef O_NOCTTY
  111. # define O_NOCTTY 0
  112. #endif
  113.  
  114. /***************************************************************/
  115.  
  116.     static void
  117. initpty(f)
  118.     int f;
  119. {
  120. #ifdef POSIX
  121.     tcflush(f, TCIOFLUSH);
  122. #else
  123. # ifdef TIOCFLUSH
  124.     (void) ioctl(f, TIOCFLUSH, (char *) 0);
  125. # endif
  126. #endif
  127. #ifdef LOCKPTY
  128.     (void) ioctl(f, TIOCEXCL, (char *) 0);
  129. #endif
  130. }
  131.  
  132. /***************************************************************/
  133.  
  134. #if defined(OSX) && !defined(PTY_DONE)
  135. #define PTY_DONE
  136.     int
  137. OpenPTY(ttyn)
  138.     char **ttyn;
  139. {
  140.     register int f;
  141.     static char TtyName[32];
  142.  
  143.     if ((f = open_controlling_pty(TtyName)) < 0)
  144.         return -1;
  145.     initpty(f);
  146.     *ttyn = TtyName;
  147.     return f;
  148. }
  149. #endif
  150.  
  151. /***************************************************************/
  152.  
  153. #if (defined(sequent) || defined(_SEQUENT_)) && !defined(PTY_DONE)
  154. #define PTY_DONE
  155.     int
  156. OpenPTY(ttyn)
  157.     char **ttyn;
  158. {
  159.     char *m, *s;
  160.     register int f;
  161.     /* used for opening a new pty-pair: */
  162.     static char PtyName[32];
  163.     static char TtyName[32];
  164.  
  165.     if ((f = getpseudotty(&s, &m)) < 0)
  166.         return -1;
  167. #ifdef _SEQUENT_
  168.     fvhangup(s);
  169. #endif
  170.     strncpy(PtyName, m, sizeof(PtyName));
  171.     strncpy(TtyName, s, sizeof(TtyName));
  172.     initpty(f);
  173.     *ttyn = TtyName;
  174.     return f;
  175. }
  176. #endif
  177.  
  178. /***************************************************************/
  179.  
  180. #if defined(__sgi) && !defined(PTY_DONE)
  181. #define PTY_DONE
  182.     int
  183. OpenPTY(ttyn)
  184.     char **ttyn;
  185. {
  186.     int f;
  187.     char *name; 
  188.     RETSIGTYPE (*sigcld)__ARGS(SIGPROTOARG);
  189.  
  190.     /*
  191.      * SIGCHLD set to SIG_DFL for _getpty() because it may fork() and
  192.      * exec() /usr/adm/mkpts
  193.      */
  194.     sigcld = signal(SIGCHLD, SIG_DFL);
  195.     name = _getpty(&f, O_RDWR | O_NONBLOCK | O_EXTRA, 0600, 0);
  196.     signal(SIGCHLD, sigcld);
  197.  
  198.     if (name == 0)
  199.         return -1;
  200.     initpty(f);
  201.     *ttyn = name;
  202.     return f;
  203. }
  204. #endif
  205.  
  206. /***************************************************************/
  207.  
  208. #if defined(MIPS) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
  209. #define PTY_DONE
  210.     int
  211. OpenPTY(ttyn)
  212.     char **ttyn;
  213. {
  214.     register int f;
  215.     struct stat buf;
  216.     /* used for opening a new pty-pair: */
  217.     static char PtyName[32];
  218.     static char TtyName[32];
  219.  
  220.     strcpy(PtyName, "/dev/ptc");
  221.     if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_NONBLOCK | O_EXTRA)) < 0)
  222.         return -1;
  223.     if (fstat(f, &buf) < 0)
  224.     {
  225.         close(f);
  226.         return -1;
  227.     }
  228.     sprintf(TtyName, "/dev/ttyq%d", minor(buf.st_rdev));
  229.     initpty(f);
  230.     *ttyn = TtyName;
  231.     return f;
  232. }
  233. #endif
  234.  
  235. /***************************************************************/
  236.  
  237. #if defined(SVR4) && !defined(PTY_DONE)
  238. #define PTY_DONE
  239.     int
  240. OpenPTY(ttyn)
  241.     char **ttyn;
  242. {
  243.     register int f;
  244.     char *m, *ptsname();
  245.     int unlockpt __ARGS((int)), grantpt __ARGS((int));
  246.     RETSIGTYPE (*sigcld)__ARGS(SIGPROTOARG);
  247.     /* used for opening a new pty-pair: */
  248.     static char PtyName[32];
  249.     static char TtyName[32];
  250.  
  251.     strcpy(PtyName, "/dev/ptmx");
  252.     if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_EXTRA)) == -1)
  253.         return -1;
  254.  
  255.     /*
  256.      * SIGCHLD set to SIG_DFL for grantpt() because it fork()s and
  257.      * exec()s pt_chmod
  258.      */
  259.     sigcld = signal(SIGCHLD, SIG_DFL);
  260.     if ((m = ptsname(f)) == NULL || grantpt(f) || unlockpt(f))
  261.     {
  262.         signal(SIGCHLD, sigcld);
  263.         close(f);
  264.         return -1;
  265.     } 
  266.     signal(SIGCHLD, sigcld);
  267.     strncpy(TtyName, m, sizeof(TtyName));
  268.     initpty(f);
  269.     *ttyn = TtyName;
  270.     return f;
  271. }
  272. #endif
  273.  
  274. /***************************************************************/
  275.  
  276. #if defined(_AIX) && defined(HAVE_DEV_PTC) && !defined(PTY_DONE)
  277. #define PTY_DONE
  278.  
  279. #ifdef _IBMR2
  280. int aixhack = -1;
  281. #endif
  282.  
  283.     int
  284. OpenPTY(ttyn)
  285.     char **ttyn;
  286. {
  287.     register int f;
  288.     /* used for opening a new pty-pair: */
  289.     static char PtyName[32];
  290.     static char TtyName[32];
  291.  
  292.     /* a dumb looking loop replaced by mycrofts code: */
  293.     strcpy (PtyName, "/dev/ptc");
  294.     if ((f = open (PtyName, O_RDWR | O_NOCTTY | O_EXTRA)) < 0)
  295.         return -1;
  296.     strncpy(TtyName, ttyname(f), sizeof(TtyName));
  297.     if (geteuid() && access(TtyName, R_OK | W_OK))
  298.     {
  299.         close(f);
  300.         return -1;
  301.     }
  302.     initpty(f);
  303. # ifdef _IBMR2
  304.     if (aixhack >= 0)
  305.         close(aixhack);
  306.     if ((aixhack = open(TtyName, O_RDWR | O_NOCTTY | O_EXTRA)) < 0)
  307.     {
  308.         close(f);
  309.         return -1;
  310.     }
  311. # endif
  312.     *ttyn = TtyName;
  313.     return f;
  314. }
  315. #endif
  316.  
  317. /***************************************************************/
  318.  
  319. #ifndef PTY_DONE
  320.     int
  321. OpenPTY(ttyn)
  322.     char **ttyn;
  323. {
  324.     register char *p, *q, *l, *d;
  325.     register int f;
  326.     /* used for opening a new pty-pair: */
  327.     static char PtyName[32];
  328.     static char TtyName[32];
  329.  
  330.     debug("OpenPTY: Using BSD style ptys.\n");
  331.     strcpy(PtyName, PtyProto);
  332.     strcpy(TtyName, TtyProto);
  333.     for (p = PtyName; *p != 'X'; p++)
  334.         ;
  335.     for (q = TtyName; *q != 'X'; q++)
  336.         ;
  337.     for (l = PTYRANGE0; (*p = *l) != '\0'; l++)
  338.     {
  339.         for (d = PTYRANGE1; (p[1] = *d) != '\0'; d++)
  340.         {
  341.             debug1("OpenPTY tries '%s'\n", PtyName);
  342.             if ((f = open(PtyName, O_RDWR | O_NOCTTY | O_EXTRA)) == -1)
  343.                 continue;
  344.             q[0] = *l;
  345.             q[1] = *d;
  346.             if (geteuid() && access(TtyName, R_OK | W_OK))
  347.             {
  348.                 close(f);
  349.                 continue;
  350.             }
  351. #if defined(sun) && defined(TIOCGPGRP) && !defined(SUNOS3)
  352.             /* Hack to ensure that the slave side of the pty is
  353.              * unused. May not work in anything other than SunOS4.1
  354.              */
  355.             {
  356.                 int pgrp;
  357.  
  358.                 /* tcgetpgrp does not work (uses TIOCGETPGRP)! */
  359.                 if (ioctl(f, TIOCGPGRP, (char *)&pgrp) != -1 || errno != EIO)
  360.                 {
  361.                     close(f);
  362.                     continue;
  363.                 }
  364.             }
  365. #endif
  366.             initpty(f);
  367.             *ttyn = TtyName;
  368.             return f;
  369.         }
  370.     }
  371.     return -1;
  372. }
  373. #endif
  374.  
  375. /* putenv.c */
  376.  
  377. /* Copyright (c) 1993
  378.  *        Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
  379.  *        Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
  380.  * Copyright (c) 1987 Oliver Laumann
  381.  *
  382.  * This program is free software; you can redistribute it and/or modify
  383.  * it under the terms of the GNU General Public License as published by
  384.  * the Free Software Foundation; either version 2, or (at your option)
  385.  * any later version.
  386.  *
  387.  * This program is distributed in the hope that it will be useful,
  388.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  389.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  390.  * GNU General Public License for more details.
  391.  *
  392.  * You should have received a copy of the GNU General Public License
  393.  * along with this program (see the file COPYING); if not, write to the
  394.  * Free Software Foundation, Inc.,
  395.  * 59 Temple Place - Suite 330, Boston, MA    02111-1307, USA
  396.  *
  397.  ****************************************************************
  398.  */
  399.  
  400. /*
  401.  *    putenv    --    put value into environment
  402.  *
  403.  *    Usage:    i = putenv (string)
  404.  *      int i;
  405.  *      char    *string;
  406.  *
  407.  *    where string is of the form <name>=<value>.
  408.  *    Putenv returns 0 normally, -1 on error (not enough core for malloc).
  409.  *
  410.  *    Putenv may need to add a new name into the environment, or to
  411.  *    associate a value longer than the current value with a particular
  412.  *    name.  So, to make life simpler, putenv() copies your entire
  413.  *    environment into the heap (i.e. malloc()) from the stack
  414.  *    (i.e. where it resides when your process is initiated) the first
  415.  *    time you call it.
  416.  *
  417.  *    HISTORY
  418.  *    3-Sep-91 Michael Schroeder (mlschroe). Modified to behave as
  419.  *      as putenv.
  420.  * 16-Aug-91 Tim MacKenzie (tym) at Monash University. Modified for
  421.  *      use in screen (iScreen) (ignores final int parameter)
  422.  * 14-Oct-85 Michael Mauldin (mlm) at Carnegie-Mellon University
  423.  *        Ripped out of CMU lib for Rob-O-Matic portability
  424.  * 20-Nov-79  Steven Shafer (sas) at Carnegie-Mellon University
  425.  *      Created for VAX.    Too bad Bell Labs didn't provide this.    It's
  426.  *      unfortunate that you have to copy the whole environment onto the
  427.  *      heap, but the bookkeeping-and-not-so-much-copying approach turns
  428.  *      out to be much hairier.  So, I decided to do the simple thing,
  429.  *      copying the entire environment onto the heap the first time you
  430.  *      call putenv(), then doing realloc() uniformly later on.
  431.  */
  432. /* #include "rcs.h" */
  433. /* RCS_ID("$Id: putenv.c,v 1.1.1.1 1993/06/16 23:51:15 jnweiger Exp $ FAU") */
  434.  
  435. /* #include "config.h" */
  436.  
  437. #if !defined(HAVE_SETENV) && !defined(HAVE_PUTENV)
  438.  
  439. #if 0            /* don't want these, will break with some compilers */
  440. char  *malloc __ARGS((int));
  441. char  *realloc __ARGS((char *, int));
  442. void   free __ARGS((char *));
  443. int    sprintf __ARGS((char *, char *, ...));
  444. #endif
  445.  
  446. #define EXTRASIZE 5           /* increment to add to env. size */
  447.  
  448. static int    envsize = -1;     /* current size of environment */
  449. extern char **environ;          /* the global which is your env. */
  450.  
  451. static int    findenv();          /* look for a name in the env. */
  452. static int    newenv();         /* copy env. from stack to heap */
  453. static int    moreenv();          /* incr. size of env. */
  454.  
  455.     int
  456. putenv(string)
  457.     char *string;
  458.     register int    i;
  459.     register char *p;
  460.  
  461.     if (envsize < 0)
  462.     {                            /* first time putenv called */
  463.         if (newenv() < 0)            /* copy env. to heap */
  464.             return -1;
  465.     }
  466.  
  467.     i = findenv(string);            /* look for name in environment */
  468.  
  469.     if (i < 0)
  470.     {                    /* name must be added */
  471.         for (i = 0; environ[i]; i++);
  472.         if (i >= (envsize - 1))
  473.         {                        /* need new slot */
  474.             if (moreenv() < 0)
  475.                 return -1;
  476.         }
  477.         p = malloc(strlen(string) + 1);
  478.         if (p == 0)                /* not enough core */
  479.             return -1;
  480.         environ[i + 1] = 0;        /* new end of env. */
  481.     }
  482.     else
  483.     {                    /* name already in env. */
  484.         p = realloc(environ[i], strlen(string) + 1);
  485.         if (p == 0)
  486.             return -1;
  487.     }
  488.     sprintf(p, "%s", string); /* copy into env. */
  489.     environ[i] = p;
  490.  
  491.     return 0;
  492. }
  493.  
  494.     static int
  495. findenv(name)
  496.     char *name;
  497. {
  498.     register char *namechar, *envchar;
  499.     register int    i, found;
  500.  
  501.     found = 0;
  502.     for (i = 0; environ[i] && !found; i++)
  503.     { 
  504.         envchar = environ[i];
  505.         namechar = name;
  506.         while (*namechar && *namechar != '=' && (*namechar == *envchar))
  507.         { 
  508.             namechar++;
  509.             envchar++;
  510.         }
  511.         found = ((*namechar == '\0' || *namechar == '=') && *envchar == '=');
  512.     }
  513.     return found ? i - 1 : -1;
  514. }
  515.  
  516.     static int
  517. newenv()
  518.     register char **env, *elem;
  519.     register int i, esize;
  520.  
  521.     for (i = 0; environ[i]; i++)
  522.         ;
  523.     esize = i + EXTRASIZE + 1;
  524.     env = (char **)malloc(esize * sizeof (elem));
  525.     if (env == 0)
  526.         return -1;
  527.  
  528.     for (i = 0; environ[i]; i++)
  529.     { 
  530.         elem = malloc(strlen(environ[i]) + 1);
  531.         if (elem == 0)
  532.             return -1;
  533.         env[i] = elem;
  534.         strcpy(elem, environ[i]);
  535.     }
  536.  
  537.     env[i] = 0;
  538.     environ = env;
  539.     envsize = esize;
  540.     return 0;
  541. }
  542.  
  543.     static int
  544. moreenv()
  545.     register int    esize;
  546.     register char **env;
  547.  
  548.     esize = envsize + EXTRASIZE;
  549.     env = (char **)realloc((char *)environ, esize * sizeof (*env));
  550.     if (env == 0)
  551.         return -1;
  552.     environ = env;
  553.     envsize = esize;
  554.     return 0;
  555. }
  556.  
  557. #endif /* !defined(HAVE_SETENV) && !defined(HAVE_PUTENV) */
  558.